/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * bocciawii
 * Copyright (C) Grupo de trabajo ULE 2010 <ulewii@googlegroups.com>
 * 
 * bocciawii is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * bocciawii is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _ELEMENTO_DINAMICO_H_
#define _ELEMENTO_DINAMICO_H_
#include "elemento-estacionario.h"

#define DUREZA_BLANDA 0
#define DUREZA_SEMI 1
#define DUREZA_DURA 2

#define COEFICIENTE_BLANDA 0.5
#define COEFICIENTE_MEDIA 0.3
#define COEFICIENTE_DURA 0.2

#define RESTITUCION_BLANDA 0.3
#define RESTITUCION_MEDIA 0.6
#define RESTITUCION_DURA 0.9

#define RADIO_BOLA 0.0425
#define GRAVEDAD 9.80665

//Palabra de blender 
// más es un término relativo, quiero referirme que el exterior está
// la cantidad indicada hacia el exterior del campo
#define LIMITE_NORTE -10.777 // 10.727 más 0.05 por línea 
#define LIMITE_ESTE 5.48 // 5.43 más 0.05 por línea 
#define LIMITE_OESTE -0.520 // 0.470 más 0.05 por línea
#define PUNTA_TRIANGULO_X 2.48 // 2.48 y punto
#define PUNTA_TRIANGULO_Y -2.726 // 2.776 más 0.05 por línea
#define BASE_TRIANGULO_Y -4.226 // 4.226, y punto


/**
 * @brief Clase para los elementos dinámicos del juego.
 *
 * Hereda procedimientos y variables públicos y protegidos de la clase 
 *  ElementoEstacionario, como carga de texturas, de modelo, etcétera.
 * 
 * Otorga "velocidad" y distancias a los objetos estacionarios.
 *
 * Las mismas restricciones que se tenían para los <code>ElementoEstacionario</code>
 * existen tambień para nuestros elementos dinámicos.
 */
class ElementoDinamico:public ElementoEstacionario 
{




public:
	/** 
	 * @brief Constructor de la clase
	 *
	 * Constructor sencillo, inicializa variables
	 */
	ElementoDinamico(int dureza, std::string equipo);

	/**
	 * @brief Asigna valores iniciales a las propiedades cinéticas de las bolas
	 *
	 * Inicializa y calcula los parámetros iniciales asociados a la bola 
	 * @param velocidad
	 * @param angulo
	 */
	void Init(float velocidad, float angulo);

	/**
	 * @brief Inicializador de valores de dirección
	 *
	 * Asigna velocidad lineal en forma de vector de dirección unitario
	 *
	 * @param x Float con la velocidad en el eje X
	 * @param y Float con la velocidad en el eje Y
	 * @param z Float con la velocidad en el eje Z
	 */
	void Dir(float x, float y, float z);

	/**
	 * @brief Setter para velocidad
	 *
	 * Asigna velocidad lineal en forma de escalar
	 * @param v_hor Float con la velocidad horizontal
	 * @param v_vert Float con la velocidad vertical
	 */
	void Vel(float v_hor, float v_vert);

	/**
	 * @brief Setter para velocidad de rotación
	 *
	 * Asigna una velocidad de giro
	 * @param x Float con la velocidad de giro con eje de revolución X
	 * @param y Float con la velocidad de giro con eje de revolución Y
	 * @param z Float con la velocidad de giro con eje de revolución Z
	 */
	void Ang(float x, float y, float z);

	/**
	 * @brief Setter para velocidad
	 *
	 * Actualiza la velocidad lineal mediante una diferencia especificada
	 * @param x Float que determina el aumento (o disminución) de la velocidad en X
	 * @param y Float que determina el aumento (o disminución) de la velocidad en Y
	 * @param z Float que determina el aumento (o disminución) de la velocidad en Z
	 */
	void VelIncremental (float x, float y, float z);

	/**
	 * @brief Setter para velocidad de rotación
	 *
	 * Actualiza una velocidad de giro mediante una diferencia especificada
	 * @param rx Float que determina el aumento (o disminución) de la velocidad de giro en X
	 * @param ry Float que determina el aumento (o disminución) de la velocidad de giro en Y
	 * @param rz Float que determina el aumento (o disminución) de la velocidad de giro en Z
	 */
	void AngIncremental (float rx, float ry, float rz);


	/**
	 * @brief Ejecuta física
	 *
	 * Actualiza la posición (rotación y localización) del objeto en función de una diferencia de tiempo
	 * @param milis Float (milisegundos) que marca el tiempo para el cual calcular el movimiento
	 */
	void ActualizarPosicion (float milis);

	
	/**
	 * @brief Constructor de la clase
	 *
	 * Informa sobre si el objeto está en movimiento
	 * @return 1 si está en movimiento, 0 de lo contrario
	 */
	int EnMovimiento(); 

	/**
	 * @brief Medición de distancia a otro elemento dinámico
	 *
	 * Calcula la distancia de este elemento dinámico a otro dado.
	 * @param el ElementoDinamico al que calcular la distancia
	 * @return distancia al elemento dinámico
	 */
	float Distancia(ElementoDinamico* el);

	/**
	 * @brief Getter de dirección
	 *
	 * Devuelve la dirección que tiene la bola
	 * @return float[3] con componentes de dirección
	 */
	inline float* GetDireccion()
	{ return velocidad_lineal; }
	
	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */
	inline float GetVelocidadHorizontal()
	{ return velocidad_escalar_horizontal; }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */
	inline float GetVelocidadVertical()
	{ return velocidad_escalar_vertical; }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */
	inline std::string GetEquipo()
	{   return _equipo;  }
	
	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */
	inline int GetIndiceDureza()
	{   return _dureza;	 }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */
	inline int Lanzada()
	{   return _bolaLanzada;	}

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */
	inline void SetColisiona()
	{ provoca_colision = 1; }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */	
	inline void SetNoColisiona()
	{ provoca_colision = 0; }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */	
	inline int GetColision()
	{return provoca_colision;}

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */	
	inline float GetCoeficiente()
	{ return coeficiente; }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */	
	inline float GetRestitucion()
	{ return restitucion; }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */	
	int DentroCancha();

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */	
	inline int Lanzar()
	{	_bolaLanzada = 1;   }

	/**
	 * @brief breve
	 *
	 * ampliada
	 * @return 
	 */	
	inline int Reset()
	{	_bolaLanzada = 0;   }


protected:  
	/// Nuestro vector velocidad de traslación
	float velocidad_lineal[3];
	/// Nuestra vector velocidad de rotación
	float velocidad_angular[3]; 
	/// Identificador del equipo al que pertenece la bola
	std::string _equipo;
	/// 0 ignorar, 1 utilizar para colisiones
	int _bolaLanzada;
	/// Indice de dureza de la bola
	int _dureza;
	///
	float coeficiente;
	///
	float restitucion;
	///
	int provoca_colision;





private:
	float velocidad_escalar_horizontal;
	float velocidad_escalar_vertical;

	float posicion_caida[3]; /// El centro de nuestro objeto
	float tiempo_acumulado;
	float tiempo_aire;
};

#endif // _ELEMENTO_DINAMICO_H_
